//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	AddonManager.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Smart.Common
{
	/// <summary>
	/// Addon manager class
	/// </summary>
	public class AddonManager : IAddonManager
	{
		public SPServicesInstance Services { get; set; }

		/// <summary>
		/// Addons collection
		/// </summary>
		public AddonList Addons { get; protected set; }

		/// <summary>
		/// Addons loaded flag
		/// </summary>
		public bool Loaded { get; protected set; }

		[MethodImpl(MethodImplOptions.Synchronized)]
		public string[] GetAddons()
		{
			var addonlist = Services.Configuration.GetValue(Const.Context.AddonConfigListKey, null);

			return
				string.IsNullOrEmpty(addonlist)
					? new string[] { }
					: addonlist.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		public void SetAddons(string[] addons)
		{
			Services.Configuration.SetValue(SPH.GetRootWeb(), Const.Context.AddonConfigListKey, addons.Where(item => !string.IsNullOrEmpty(item)).CastToString("\n"));
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		public string[] GetRegisteredAddons()
		{
			var addonlist = Services.Configuration.GetValue(Const.Context.RegisteredAddonConfigListKey, null);

			return
				string.IsNullOrEmpty(addonlist)
					? new string[] { }
					: addonlist.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
		}

		[MethodImpl(MethodImplOptions.Synchronized)]
		public void SetRegisteredAddons(string[] addons)
		{
			Services.Configuration.SetValue(SPH.GetRootWeb(), Const.Context.RegisteredAddonConfigListKey, addons.Where(item => !string.IsNullOrEmpty(item)).CastToString("\n"));
		}

		/// <summary>
		/// Load addons
		/// </summary>
		[MethodImpl(MethodImplOptions.Synchronized)]
		public void Load()
		{
			if (Loaded)
				return;

			H.LT("AddonManager: loading and registering addons...");

			Addons.Clear();

			var addonsList = GetAddons();

			foreach (var addon in addonsList)
			{
				Addons.Add(new AddonInfo(addon));
			}

			var registrationChanged = false;
			var registered = new HashSet<string>(GetRegisteredAddons(), StringComparer.OrdinalIgnoreCase);

			foreach (var ai in Addons)
			{
				if (!registered.Contains(ai.FullName) && ai.Register())
				{
					registrationChanged = true;
					registered.Add(ai.FullName);
				}

				ai.Load();
			}

			if (registrationChanged)
				SetRegisteredAddons(registered.ToArray());

			Loaded = true;

			H.LT("AddonManager: addons registered and loaded!");
		}

		/// <summary>
		/// Reload addons
		/// </summary>
		[MethodImpl(MethodImplOptions.Synchronized)]
		public void Reload()
		{
			Loaded = false;

			Load();
		}

		/// <summary>
		/// Register addon
		/// </summary>
		[MethodImpl(MethodImplOptions.Synchronized)]
		public void Reg(string addon)
		{
			var addonsList = GetAddons();

			if (!addonsList.Contains(addon, StringComparer.OrdinalIgnoreCase))
			{
				addonsList = addonsList.Concat(new[] { addon }).ToArray();

				SetAddons(addonsList);
			}
		}

		/// <summary>
		/// Unregister addon
		/// </summary>
		[MethodImpl(MethodImplOptions.Synchronized)]
		public void Unreg(string addon)
		{
			var addonsList = GetAddons();

			addonsList = addonsList.Except(new[] { addon }, StringComparer.OrdinalIgnoreCase).ToArray();

			SetAddons(addonsList);
		}

		/// <summary>
		/// Addon manager class
		/// </summary>
		public AddonManager(SPServicesInstance services)
		{
			Services = services;

			Addons = new AddonList();
		}
	}
}